package edu.upf.grupoe.p2ppicture.DBAccessEngine.implementations;

import edu.upf.grupoe.p2ppicture.DBAcessEngine.Interfaces.XmlDbDataSource;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Properties;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.xmldb.api.base.*;
import org.xmldb.api.modules.*;
import org.xmldb.api.*;
//import org.exist.xmldb.DatabaseImpl;

/**
 *
 * @author Alberto Llor
 * NIa 69808
 * 
 */
public class XMLDBDatasourceImpl implements XmlDbDataSource {

    private static Log logger=LogFactory.getLog("Main");
    private Database db;
    
    private String user;
    private String password;
    private String uri;
    private String driver;
    
    public XMLDBDatasourceImpl() {
        db=null;
        user="";
        password="";
        uri="";
        driver="";
    }
    /**
     * This method returns a XMLDB collection, having the user, uri and password fiels from setConfig() method
     * @return Collection
     * @throws XMLDBException 
     */
    public Collection getCollection() throws XMLDBException {
        uri=startDBConnection();
        if(logger.isDebugEnabled()){
            logger.debug("URI: "+uri);
            logger.debug("User:"+user);
            logger.debug("Password: "+password);
            logger.debug("Driver:"+driver);
        }
        org.xmldb.api.base.Collection myCollection=null;
        
        // Collection retrieving
        myCollection = DatabaseManager.getCollection(uri, user, password);
        if(logger.isDebugEnabled()){
            logger.info("Collection: "+myCollection.getName());
        }
        
        return myCollection;
    }
    /**
     * This method returns a XMLDB Collection passing it a user and a password
     * @param un
     * @param p
     * @return Collection
     * @throws XMLDBException 
     */
    public Collection getCollection(String un, String p) throws XMLDBException{
        uri=startDBConnection();
        if(logger.isDebugEnabled()){
            logger.debug("URI: "+uri);
            logger.debug("User:"+user);
            logger.debug("Password: "+password);
            logger.debug("Driver:"+driver);
        }
        org.xmldb.api.base.Collection myCollection = null;
        
        //Collection retrieving
        myCollection = DatabaseManager.getCollection(uri,un,p);
        return myCollection;
    } 
     /**
      * This method establish a connection with the DB server. It returns the DB URI
      * @return String
      */
     public String startDBConnection () {
         Properties xmldbProp = null;
         
         try {
             xmldbProp=this.setConfig();
         } catch (IOException ioe) {
             if(logger.isDebugEnabled())
                logger.error("Error getting the XMLDB Property file ", ioe);
         }
         
         if (null!=xmldbProp) {
             
             driver=xmldbProp.getProperty("XmlDbDataSource/driverClassName");
             
             uri = xmldbProp.getProperty("XmlDbDataSource/url");
                       
             user = xmldbProp.getProperty("XmlDbDatasource/user");
             
             password = xmldbProp.getProperty("XmlDbDatasource/password");
             if(logger.isDebugEnabled())
                logger.info(driver + " "+ uri + " " +user+" "+password);
             try {
                 Class myClass = Class.forName(driver);
                 
                 db=(Database) myClass.newInstance();
                 
                 DatabaseManager.registerDatabase(db);
                 
             } catch (ClassNotFoundException cnfe) {
                 if(logger.isDebugEnabled())
                    logger.error("ERROR: "+cnfe.getMessage());
             } catch (InstantiationException ie) {
                 if(logger.isDebugEnabled())
                 logger.error("ERROR: "+ie.getMessage());
             } catch (IllegalAccessException iae) {
                 if(logger.isDebugEnabled())
                 logger.error("ERROR: "+iae.getMessage());
             } catch (XMLDBException xmldbe) {
                 if(logger.isDebugEnabled())
                 logger.error("ERROR: "+xmldbe.getMessage());
             } 
         } else {
             if(logger.isDebugEnabled())
                logger.error("ERROR trying to obtain the properties");   
         }
         return uri;
    }
     
     /**
      * This method reads database.properties file and extracts the required information
      * @return Properties
      * @throws IOException 
      */
     private Properties setConfig() throws IOException {
         final Properties compProperties=new Properties();
         final InputStream is=XMLDBDatasourceImpl.class.getClassLoader().getResourceAsStream("database.properties");
         InputStreamReader isr=null;
         try {
            isr=new InputStreamReader(is, "UTF-8");
            compProperties.load(isr);
         } finally {
             if (isr!=null) {
                 isr.close();
             }
         }
         return compProperties;
     }
     public String getUser(){
         return user;
     }
     public String getPassword(){
         return password;
     }
     public String getURI(){
         return uri;
     }
     public String getDriver(){
         return driver;
     }
}